//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Linq;

using ProjectBase.Core;
using ProjectBase.Mvc.Models;

using $prjsn$.Common;
using $prjsn$.Common.Models;
using $prjsn$.Entity;

namespace $safeprojectname$.Models
{
    /// <summary>
    /// All data and binding properties for 'FieldObject' Views
    /// </summary>
    public class FieldObjectModel<TField> : EntityModel<TField, int, FieldFilter>
        , IFieldObjectModel<TField>
        where TField : FieldObject, new()
    {
        const string AddColumnTemplate = "ALTER TABLE [ems].[{0}Additional] ADD [{1}] {2} NULL";
        const string MappingTemplatePersistent = @"
<many-to-one name=""{0}"" not-null=""false"" column=""{1}"" class=""{2}"" />
<property name=""{0}Id""  not-null=""false"" column=""{1}"" type=""integer""
    insert=""false"" update=""false"" />";
        const string MappingTemplateValueType = @"
<property name=""{0}""  not-null=""false""  column=""{1}""  type=""{2}"" />";
        const string MappingTemplateString = @"
<property name=""{0}""  not-null=""false""  column=""{1}""  type=""string""  length=""{2}"" />";
        readonly static IDictionary<string, string> CsharpToSql = new Dictionary<string, string>
        {
             {"int", "int"},
             {"int32", "int"},
             {"integer", "int"},

             {"bool", "bit"},
             {"boolean", "bit"},

             {"decimal", "decimal(14,5)"},

             {"datetime", "datetime"},
        };
        readonly static IDictionary<string, string> CsharpToHbm = new Dictionary<string, string>
        {
             {"int", "integer"},
             {"int32", "integer"},
             {"integer", "integer"},

             {"bool", "bool"},
             {"boolean", "bool"},

             {"decimal", "decimal"},

             {"datetime", "DateTime"},
        };


        protected virtual string TryBuildMapping()
        {
            if (Item.IsNull() || Item.IsTransient() || Item.IsStatic)
            {
                return string.Empty;
            }

            var propertyName = Item.PropertyName;
            var columnName = Item.ColumnName;
            var type = Item.DataType;

            if (Item.Type.HasType<IPersistentObject>())
            {
                type = Item.Type.Name;
                return MappingTemplatePersistent.FormatWith(propertyName, columnName, type);
            }
            if (Item.Type.HasType<string>())
            {
                var length = Item.Length;
                return MappingTemplateString.FormatWith(propertyName, columnName, length);
            }

            type = CsharpToHbm[Item.DataType.ToLowerInvariant()];
            return MappingTemplateValueType.FormatWith(propertyName, columnName, type);
        }

        protected virtual string TryBuildScripts()
        {
            if (Item.IsNull() || Item.IsTransient() || Item.IsStatic)
            {
                return string.Empty;
            }

            var tableName = typeof(TField).Name.TrimEnd("Field");
            var columnName = Item.ColumnName;

            var type = Item.DataType;

            if (Item.Type.HasType<IPersistentObject>())
            {
                type = "int";
                return AddColumnTemplate.FormatWith(tableName, columnName, type);
            }

            if (Item.Type.HasType<string>())
            {
                type = "nvarchar({0})".FormatWith(Item.Length);
                return AddColumnTemplate.FormatWith(tableName, columnName, type);
            }

            type = CsharpToSql[Item.DataType.ToLowerInvariant()];
            return AddColumnTemplate.FormatWith(tableName, columnName, type);
        }

        public virtual string PersistenceMapping { get { return TryBuildMapping(); } }
        public virtual string PersistenceScripts { get { return TryBuildScripts(); } }
        public IDictionary<string, string> DataTypes { get; set; }
    }
}

